<!--
 厦门大学计算机专业 | 前华为工程师
 专注《零基础学编程系列》https://lblbc.cn/blog
 包含：Java | 安卓 | 前端 | Flutter | iOS | 小程序 | 鸿蒙
 公众号：蓝不蓝编程
-->
<template>
  <div class="container">
    <div class="score-container">
      <text class="score">得分：{{ score }}</text>
    </div>
    <div class="row" v-for="(item, index) in squares" :key="index">
      <div
        :class="'square ' + (item === 0 ? 'unfocused' : 'focused')"
        v-for="(item, index1) in item"
        :key="index1"
      ></div>
    </div>
    <div class="btn-row">
      <div class="op-button" @click="movePieceLeft">向左</div>
      <div class="op-button" @click="movePieceRight">向右</div>
      <div class="op-button" @click="dropPieceToBottom">向下</div>
      <div class="op-button" @click="rotatePiece">旋转</div>
    </div>
    <!-- 游戏结束提示视图 -->
    <div class="game-over" v-if="gameOver">
      <text class="game-over-text">游戏结束</text>
      <div class="op-button" @click="restartGame">重新开始</div>
    </div>
  </div>
</template>

<script>
import { Block, shapes } from './block.js' // 确保路径正确

export default {
  name: 'LblbcHome',
  data() {
    return {
      squares: [], // 初始化一个20x10的二维数组
      currentPiece: null,
      piecePosition: {
        x: 0,
        y: 0
      },
      intervalId: null,
      score: 0, // 初始化得分
      gameOver: false // 游戏是否结束
    }
  },
  mounted() {
    console.log('onLoad')
    this.initSquares()
    this.spawnPiece()
    this.startPieceDropping()
  },

  methods: {
    initSquares: function () {
      this.squares = Array(20)
        .fill()
        .map(() => Array(10).fill(0))
    },

    spawnPiece: function () {
      var randomIndex = Math.floor(Math.random() * shapes.length)
      const newPiece = new Block(
        shapes[randomIndex].shape
      )
      var posX = parseInt((10 - newPiece.shape[0].length) / 2)
      this.currentPiece = newPiece
      this.piecePosition = {
        x: posX,
        y: 0
      }
    },

    drawPiece: function (isToLock) {
      const squares = this.squares
      const piece = this.currentPiece.shape
      const position = this.piecePosition
      for (let i = 0; i < piece.length; i++) {
        for (let j = 0; j < piece[i].length; j++) {
          if (piece[i][j]) {
            if (isToLock) {
              squares[position.y + i][position.x + j] = 1
            } else {
              squares[position.y + i][position.x + j] = piece[i][j] // 假设1表示方块
            }
          }
        }
      }

      this.squares = squares
    },

    dropPiece: function () {
      // 更新位置
      const newPosition = {
        ...this.piecePosition,
        y: this.piecePosition.y + 1
      }

      // 重新绘制形状
      this.drawPieceAt(newPosition)
    },

    clearPiece: function () {
      const squares = this.squares
      const position = this.piecePosition
      if (position.y < 0) {
        //初始y坐标为-1，不需要清除
        return
      }
      for (let i = 0; i < squares.length; i++) {
        for (let j = 0; j < squares[i].length; j++) {
          squares[i][j] &= 1 // 清除值为2的块（即当前shape所处位置）
        }
      }
    },

    drawPieceAt: function (position) {
      this.clearPiece() // 清除旧位置的形状
      this.piecePosition = position // 更新位置
      this.drawPiece(false) // 绘制新位置的形状
    },

    startPieceDropping: function () {
      if (this.intervalId) {
        clearInterval(this.intervalId)
      }
      const intervalId = setInterval(() => {
        if (
          this.isPositionValid(this.piecePosition.y + 1, this.piecePosition.x)
        ) {
          this.dropPiece()
        } else {
          console.log('clearInterval')
          clearInterval(this.intervalId) // 停止下降
          this.lockPiece()
        }
      }, 1000)
      this.intervalId = intervalId
    },

    movePieceLeft: function () {
      // 当前piece向左移动一格
      const newPosition = {
        ...this.piecePosition,
        x: this.piecePosition.x - 1
      }
      if (this.isPositionValid(newPosition.y, newPosition.x)) {
        this.drawPieceAt(newPosition)
      }
    },

    movePieceRight: function () {
      // 当前piece向右移动一格
      const newPosition = {
        ...this.piecePosition,
        x: this.piecePosition.x + 1
      }
      if (this.isPositionValid(newPosition.y, newPosition.x)) {
        this.drawPieceAt(newPosition)
      }
    },

    rotatePiece: function () {
      if (!this.currentPiece) {
        return
      }

      // 旋转方块
      this.currentPiece.rotate()

      // 计算旋转后方块的左上角坐标，保持在原来位置
      const rotatedPosition = {
        x: this.piecePosition.x,
        y: this.piecePosition.y
      }

      // 检查旋转后的位置是否有效
      if (this.isPositionValid(rotatedPosition.y, rotatedPosition.x)) {
        // 如果位置有效，更新方块位置并重新绘制
        this.drawPieceAt(rotatedPosition)
      } else {
        // 如果位置无效，撤销旋转
        this.currentPiece.undoRotate() // 假设你有一个 undoRotate 方法来撤销旋转
        this.drawPieceAt(this.piecePosition) // 重新绘制原始位置的形状
      }
    },

    isPositionValid: function (y, x) {
      if (!this.currentPiece) {
        return false
      }
      const piece = this.currentPiece.shape
      // const x = this.data.piecePosition.x;
      const newY = y + piece.length - 1 // 新的y位置加上形状的高度

      const squares = this.squares

      // 检查新位置是否超出游戏区域底部或与现有方块冲突
      for (let row = 0; row < piece.length; row++) {
        for (let col = 0; col < piece[row].length; col++) {
          if (
            piece[row][col] &&
            (newY > 19 ||
              x + col < 0 ||
              x + col >= 10 || // 超出游戏区域左右边界
              squares[newY + row - piece.length + 1][x + col] === 1) // 与现有方块冲突
          ) {
            return false
          }
        }
      }
      return true
    },

    dropPieceToBottom: function () {
      // 循环直到方块到达底部或者无法再下降
      let newPosition = this.piecePosition
      while (this.isPositionValid(newPosition.y + 1, newPosition.x)) {
        newPosition = {
          ...newPosition,
          y: newPosition.y + 1
        }
      }
      // 锁定方块
      this.drawPieceAt(newPosition)
      this.lockPiece()
    },

    lockPiece: function () {
      // 锁定形状，即将形状的方块合并到squares中
      this.drawPiece(true)
      // 检查并清除完整的行
      this.clearLines()
      // 在清除行之前检查游戏是否结束
      if (this.isGameOver()) {
        this.gameOver = true // 设置游戏结束状态
        console.log('游戏结束！')
        // 这里可以添加结束游戏的逻辑，比如停止计时器，显示游戏结束的界面等
        return
      }
      // 可能还需要生成新的形状
      this.spawnPiece()
      this.startPieceDropping()
    },

    clearLines: function () {
      const squares = this.squares
      for (let i = 0; i < squares.length; i++) {
        if (squares[i].every((cell) => cell === 1)) {
          // 移除完整的行
          squares.splice(i, 1)
          // 在顶部添加一个空行
          squares.unshift(new Array(10).fill(0))
          i-- // 调整索引以继续检查新移动的行
          this.incrementScore(10)
        }
      }
      this.squares = squares
    },

    // 检查游戏是否结束
    isGameOver: function () {
      const firstRow = this.squares[0]
      for (let i = 0; i < firstRow.length; i++) {
        if (firstRow[i] === 1) {
          return true
        }
      }
      return false
    },

    // 重新开始游戏
    restartGame: function () {
      this.squares = Array(20)
        .fill()
        .map(() => Array(10).fill(0))
      this.currentPiece = null
      this.piecePosition = { x: 0, y: 0 }
      this.intervalId = null
      this.score = 0
      this.gameOver = false
      this.initSquares()
      this.spawnPiece()
      this.startPieceDropping()
    },

    incrementScore: function (points) {
      this.score = this.score + points
    }
  }
}
</script>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.score-container {
  font-size: 16px;
  color: #333;
  margin-bottom: 3px;
}

.score {
  font-weight: bold;
}
.row {
  display: flex;
}

.square {
  width: 33px;
  height: 33px;
  margin: 1px;
}

.focused {
  background-color: #333333;
}

.unfocused {
  background-color: #d3d3d3;
}

.btn-row {
  display: flex;
  margin-top: 5px;
  margin-bottom: 5px;
}

.op-button {
  padding: 10px 20px;
  background-color: #007aff;
  color: white;
  border: none;
  border-radius: 5px;
  margin: 10px 5px;
}
.game-over {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.game-over-text {
  font-size: 40px;
  color: #fff;
  margin-bottom: 20px;
}
</style>
